package se.spagettikod.optimist.gwt.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.StatusCodeException;

public abstract class OptimistAsyncCallback<T> implements AsyncCallback<T> {

	public abstract void onModifiedByAnotherUser();

	public abstract void onRemovedByAnotherUser();

	public abstract void onLockedByAnotherUser();

	public boolean isOptimisticFailure(Throwable caught) {
		if (isLockedByAnotherUser(caught))
			return true;
		else if (isModifiedByAnotherUser(caught))
			return true;
		else if (isRemovedByAnotherUser(caught))
			return true;
		return false;
	}

	private boolean isModifiedByAnotherUser(Throwable caught) {
		if (caught instanceof StatusCodeException) {
			StatusCodeException e = (StatusCodeException) caught;
			GWT.log(e.getMessage());
			return (e.getStatusCode() == 409 && e
					.getMessage()
					.equals("409 se.spagettikod.optimist.ModifiedByAnotherUserException"));
		}
		return false;
	}

	private boolean isRemovedByAnotherUser(Throwable caught) {
		if (caught instanceof StatusCodeException) {
			StatusCodeException e = (StatusCodeException) caught;
			GWT.log(e.getMessage());
			return (e.getStatusCode() == 410 && e
					.getMessage()
					.equals("410 se.spagettikod.optimist.RemovedByAnotherUserException"));
		}
		return false;
	}

	private boolean isLockedByAnotherUser(Throwable caught) {
		if (caught instanceof StatusCodeException) {
			StatusCodeException e = (StatusCodeException) caught;
			GWT.log(e.getMessage());
			return (e.getStatusCode() == 409 && e.getMessage().equals(
					"409 se.spagettikod.optimist.LockedByAnotherUserException"));
		}
		return false;
	}

	public void onFailure(Throwable caught) {
		if (caught instanceof StatusCodeException) {
			StatusCodeException e = (StatusCodeException) caught;
			GWT.log(e.getMessage());
			if (isModifiedByAnotherUser(caught)) {
				onModifiedByAnotherUser();
			} else if (isLockedByAnotherUser(caught)) {
				onLockedByAnotherUser();
			} else if (isRemovedByAnotherUser(caught)) {
				onRemovedByAnotherUser();
			}
		}
	}
}
